/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.SubTipoMaterial;
import entidades.TipoMaterial;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author g
 */
public class TipoMaterialJpaController implements Serializable {

    public TipoMaterialJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(TipoMaterial tipoMaterial) {
        if (tipoMaterial.getLs_subtipos() == null) {
            tipoMaterial.setLs_subtipos(new ArrayList<SubTipoMaterial>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<SubTipoMaterial> attachedLs_subtipos = new ArrayList<SubTipoMaterial>();
            for (SubTipoMaterial ls_subtiposSubTipoMaterialToAttach : tipoMaterial.getLs_subtipos()) {
                ls_subtiposSubTipoMaterialToAttach = em.getReference(ls_subtiposSubTipoMaterialToAttach.getClass(), ls_subtiposSubTipoMaterialToAttach.getId());
                attachedLs_subtipos.add(ls_subtiposSubTipoMaterialToAttach);
            }
            tipoMaterial.setLs_subtipos(attachedLs_subtipos);
            em.persist(tipoMaterial);
            for (SubTipoMaterial ls_subtiposSubTipoMaterial : tipoMaterial.getLs_subtipos()) {
                TipoMaterial oldTipoMaterialOfLs_subtiposSubTipoMaterial = ls_subtiposSubTipoMaterial.getTipoMaterial();
                ls_subtiposSubTipoMaterial.setTipoMaterial(tipoMaterial);
                ls_subtiposSubTipoMaterial = em.merge(ls_subtiposSubTipoMaterial);
                if (oldTipoMaterialOfLs_subtiposSubTipoMaterial != null) {
                    oldTipoMaterialOfLs_subtiposSubTipoMaterial.getLs_subtipos().remove(ls_subtiposSubTipoMaterial);
                    oldTipoMaterialOfLs_subtiposSubTipoMaterial = em.merge(oldTipoMaterialOfLs_subtiposSubTipoMaterial);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(TipoMaterial tipoMaterial) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoMaterial persistentTipoMaterial = em.find(TipoMaterial.class, tipoMaterial.getId());
            List<SubTipoMaterial> ls_subtiposOld = persistentTipoMaterial.getLs_subtipos();
            List<SubTipoMaterial> ls_subtiposNew = tipoMaterial.getLs_subtipos();
            List<SubTipoMaterial> attachedLs_subtiposNew = new ArrayList<SubTipoMaterial>();
            for (SubTipoMaterial ls_subtiposNewSubTipoMaterialToAttach : ls_subtiposNew) {
                ls_subtiposNewSubTipoMaterialToAttach = em.getReference(ls_subtiposNewSubTipoMaterialToAttach.getClass(), ls_subtiposNewSubTipoMaterialToAttach.getId());
                attachedLs_subtiposNew.add(ls_subtiposNewSubTipoMaterialToAttach);
            }
            ls_subtiposNew = attachedLs_subtiposNew;
            tipoMaterial.setLs_subtipos(ls_subtiposNew);
            tipoMaterial = em.merge(tipoMaterial);
            for (SubTipoMaterial ls_subtiposOldSubTipoMaterial : ls_subtiposOld) {
                if (!ls_subtiposNew.contains(ls_subtiposOldSubTipoMaterial)) {
                    ls_subtiposOldSubTipoMaterial.setTipoMaterial(null);
                    ls_subtiposOldSubTipoMaterial = em.merge(ls_subtiposOldSubTipoMaterial);
                }
            }
            for (SubTipoMaterial ls_subtiposNewSubTipoMaterial : ls_subtiposNew) {
                if (!ls_subtiposOld.contains(ls_subtiposNewSubTipoMaterial)) {
                    TipoMaterial oldTipoMaterialOfLs_subtiposNewSubTipoMaterial = ls_subtiposNewSubTipoMaterial.getTipoMaterial();
                    ls_subtiposNewSubTipoMaterial.setTipoMaterial(tipoMaterial);
                    ls_subtiposNewSubTipoMaterial = em.merge(ls_subtiposNewSubTipoMaterial);
                    if (oldTipoMaterialOfLs_subtiposNewSubTipoMaterial != null && !oldTipoMaterialOfLs_subtiposNewSubTipoMaterial.equals(tipoMaterial)) {
                        oldTipoMaterialOfLs_subtiposNewSubTipoMaterial.getLs_subtipos().remove(ls_subtiposNewSubTipoMaterial);
                        oldTipoMaterialOfLs_subtiposNewSubTipoMaterial = em.merge(oldTipoMaterialOfLs_subtiposNewSubTipoMaterial);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = tipoMaterial.getId();
                if (findTipoMaterial(id) == null) {
                    throw new NonexistentEntityException("The tipoMaterial with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoMaterial tipoMaterial;
            try {
                tipoMaterial = em.getReference(TipoMaterial.class, id);
                tipoMaterial.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The tipoMaterial with id " + id + " no longer exists.", enfe);
            }
            List<SubTipoMaterial> ls_subtipos = tipoMaterial.getLs_subtipos();
            for (SubTipoMaterial ls_subtiposSubTipoMaterial : ls_subtipos) {
                ls_subtiposSubTipoMaterial.setTipoMaterial(null);
                ls_subtiposSubTipoMaterial = em.merge(ls_subtiposSubTipoMaterial);
            }
            em.remove(tipoMaterial);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<TipoMaterial> findTipoMaterialEntities() {
        return findTipoMaterialEntities(true, -1, -1);
    }

    public List<TipoMaterial> findTipoMaterialEntities(int maxResults, int firstResult) {
        return findTipoMaterialEntities(false, maxResults, firstResult);
    }

    private List<TipoMaterial> findTipoMaterialEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(TipoMaterial.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public TipoMaterial findTipoMaterial(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(TipoMaterial.class, id);
        } finally {
            em.close();
        }
    }

    public int getTipoMaterialCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<TipoMaterial> rt = cq.from(TipoMaterial.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
